const dayjs = require("dayjs")
const {
    getAll,
    getRow,
    exec
} = require("../util/dbutil")
const {
    AssertUtils,
    IdUtils,
    RandomUtils
} = require("../util/utils")
const {
    getUserById
} = require("./user")

/**
 * 附近充电桩
 * @returns 充电桩列表
 */
const vicinityStationsList = async () => {
    return await getAll("select * from charging_stations order by km asc")
}

/**
 * 充电桩详情
 * @returns 充电桩信息
 */
const StationsDetail = async (id) => {
    const detail = await getRow("select * from charging_stations where id = ?", [id])
    AssertUtils.ObjectNotEmpty(detail, "充电桩不存在")
    return detail
}


/**
 * 创建订单
 * @returns 
 */
const StationsOrder = async (carId, csId, payId, userId) => {

    const csDetail = await getRow("select * from charging_stations where id = ?", [csId])
    AssertUtils.ObjectNotEmpty(csDetail, "充电桩不存在")
    AssertUtils.isTrue(csDetail.status == '空闲', "充电桩正在使用")

    const carDetail = await getRow("select * from car where id = ?", [carId])
    AssertUtils.ObjectNotEmpty(carDetail, "汽车不存在")

    const payDetail = await getRow("select * from charging_stations_pay where id = ?", [payId])
    AssertUtils.ObjectNotEmpty(payDetail, "金额规则不存在")
    let orderId = IdUtils.flakeId()
    await exec('INSERT INTO orders (id, money, car_id, cs_id, user_id, create_time) values (?, ?, ?, ?, ?, ?)', [orderId, payDetail.money, carId, csId, userId, new Date()])
    return orderId
}

/**
 * 支付订单
 * @returns 
 */
const StationsPay = async (orderId, payType, userId) => {
    const user = await getUserById(userId)
    const orderDetail = await getRow("select * from orders where id = ?", [orderId])
    AssertUtils.isTrue((user.money - orderDetail.money) >= 0, "余额不足")
    AssertUtils.ObjectNotEmpty(orderDetail, "订单不存在")
    AssertUtils.isTrue(orderDetail.status == '待支付', "订单已支付")
    let currentData = new Date()
    //修改状态
    exec("update charging_stations set status = '运行中' where id = ?", [orderDetail.cs_id])
    //减少用户余额
    exec("update user set money = money - ? where id = ?", [orderDetail.money, userId])
    //修改订单状态
    exec("update orders set pay_time = ?,start_time = ?, pay_type = ?, status = '进行中' where id = ?", [currentData, currentData, payType, orderId])
    return {}
}

/**
 * 结束订单
 * @returns 
 */
const StationsOverOrder = async (csId, userId) => {
    const csDetail = await getRow("select * from charging_stations where id = ?", [csId])
    AssertUtils.ObjectNotEmpty(csDetail, "充电桩不存在")
    AssertUtils.isTrue(csDetail.status == '运行中', "设备未使用")

    //每分钟多少钱
    const MinuteMoney = 2.4
    const orderDetail = await getRow("select * from orders where status = '进行中' and cs_id = ? order create_time desc limit 1", [csId])
    AssertUtils.ObjectNotEmpty(orderDetail, "设备未使用")
    AssertUtils.isTrue(userId == orderDetail.user_id, "设备占用")
    let end_time_dayjs = dayjs()
    //结束时间
    let end_time = end_time_dayjs.toDate()
    //使用的分钟数,不满一分钟按一分钟算
    let diffMinute = Math.ceil(end_time_dayjs.diff(orderDetail.start_time, 'minute', true))
    let diffMoney = Number((diffMinute * MinuteMoney).toFixed(2))

    //总金额
    let amount = orderDetail.money
    //总差额
    let amountDiff = null
    let status = '已完成'
    //订单如果未超出，就去最大值
    if (diffMoney > orderDetail.money) {
        //总金额加上差额
        amount = diffMoney + amount
        amountDiff = diffMoney
        status = '进行中'
    }
    let times = []
    for (let minute = 1; minute <= diffMinute; minute++) {
        times.push({
            cs_id: parseInt(csId),
            car_id: orderDetail.car_id,
            amount: MinuteMoney,
            minute: 1,
            date: dayjs(orderDetail.start_time).add(minute, 'minute').toDate(),
        })
    }
    //添加充电日志
    await exec("insert charging_stations_log (cs_id, car_id, amount, minute, date) VALUES ? ", [times.map(Object.values)])
    //修改订单状态
    await exec("update orders set end_time=?, charged_quantity=?, diff_money=?, amount=?, status = ? where id = ?", [end_time, RandomUtils.random(50, 100), amountDiff, amount, status, orderDetail.id])
    //修改设备状态
    await exec("update charging_stations set status='空闲' where id=?", [csId])
    return {}
}
const getOrdersStatus = async (status) => {
    return await getAll(`SELECT * FROM orders WHERE status = ?`, [status])
}
module.exports = {
    vicinityStationsList,
    StationsDetail,
    StationsOrder,
    StationsPay,
    StationsOverOrder,
    getOrdersStatus
}